[アップデート] 実行中のコンテナに乗り込んでコマンドを実行できる「ECS Exec」が公開されました
みなさん、こんにちは!
AWS事業本部の青柳@福岡オフィスです。
Amazon Elastic Container Service (ECS) において、実行中のコンテナに乗り込んでコマンドを実行できる機能「ECS Exec」が公開されました。
Amazon ECS now allows you to execute commands in a container running on Amazon EC2 or AWS Fargate
どんなものなのか、早速使ってみたいと思います。
これまでの方法
デバッグやトラブルシューティングを行うために、実行中のコンテナに乗り込んでコマンドを実行したいという時があると思います。
これまで、これをECSで行おうとする場合、コンテナを実行しているEC2インスタンスにSSHでログインした後にdocker exec
コマンドを実行するという方法が取られてきました。
この方法では、以下のような問題 (手間) がありました。
- 予めEC2インスタンスにSSHで接続できるようにしておく必要がある (SSMセッションマネージャーを使うという方法もありますが)
- 複数のEC2インスタンスでECSサービスを実行している場合、目的のコンテナが稼働しているEC2インスタンスを特定する必要がある
また、コンテナをFargateで実行している場合、そもそも上記の方法すら使えませんでした。
ECS Execでは、これらの問題が一気に解決できます。
ECS Execの仕組み
ECS Execでは、AWS Systems Manager (SSM) の「セッションマネージャー」の仕組みを使うことで、クライアントからSSMコンポーネントを経由してコンテナにアクセスすることを実現しています。
そのため、EC2インスタンスにログインする必要はありませんし、コンテナにSSHポートを開けたりする必要もありません。
SSMをベースとしているために、EC2インスタンスやFargateでSSMエージェントが動作している必要があります。
ただし、後述するように、ECS Execに対応済みの特定バージョン以降のECSインスタンス (ECS-optimized AMI) やFargate (プラットフォームバージョン) を利用することで、ユーザーが手作業でSSMエージェントをインストールしたりすることなくECS Execを利用することができます。
前提条件
ECS Execを利用するための前提条件は以下の通りです。
ECS側
前述の通り、ECS Execに対応したSSMエージェントが導入済みのEC2インスタンスまたはFargateを使用する必要があります。
- コンテナをEC2インスタンスで実行する場合:
- ECS-optimized AMIの「2021年1月20日」以降にリリースされたバージョンを使う
- コンテナをFargateで実行する場合:
- Fargateのプラットフォームバージョン「1.4.0」以降を使う
EC2インスタンスの場合は、上記対応バージョンAMIから起動したEC2インスタンスをECSクラスターに追加または置き換えてください。
Fargateの場合は、ECSサービスを作成する際にFargateのプラットフォームバージョンを「1.4.0」以上に指定するか、既存のECSサービスを更新してください。
クライアント側
コンテナ上でコマンドを実行するためにAWS CLIのaws ecs execute-command
コマンドを使います。
このコマンドを使うことができる以下のバージョンにアップデートする必要があります。
- AWS CLI v1の場合:
- バージョン 1.19.28 (2021/03/16リリース) またはそれ以降
- AWS CLI v2の場合:
2021/03/16時点で対応したバージョンがリリースされていません (今後数週間でリリース予定とのこと)
バージョン 2.1.31 (2021/03/20リリース) またはそれ以降
普段AWS CLI v2を利用されている方は、AWS CLI v1を追加でインストールするか (AWS CLIのv1とv2の共存は可能です)、AWS CLI v2が対応するのを待ちましょう。
2021/03/20更新 AWS CLI v2も対応しました!
加えて、「Session Managerプラグイン」をインストールする必要があります。
これは、AWS CLIを使ってEC2インスタンスにSSMセッションマネージャーでログインするためにaws ssm start-session
コマンドを使ったことのある方であれば、インストールしたことがあるかと思います。
まだインストールしたことがない方は、以下の手順でインストールしておきましょう。
(オプション) AWS CLI 用の Session Manager plugin をインストールする - AWS Systems Manager
なお、Session Managerプラグインのバージョン要件については特に触れられていませんが、多少古めのバージョンでも動作はしました。
念のために最新バージョンを導入することをオススメします。
ECS Execを利用するための設定
ECS Execを利用するまでの流れは以下のようになります。
- SSMセッションマネージャー関連の権限を付与したIAMロール (ECSタスクロール) を用意する
- 1で用意したECSタスクロールを使って、ECSタスク定義を新規作成または更新する
- ECSサービスで「enableExecuteCommand」の設定を有効にする
- 2で作成/更新したECSタスク定義を使って、ECSサービスを新規作成または更新する
- (ECS Execを使ってコンテナ上でコマンドを実行する)
順に説明していきます。
1. SSMセッションマネージャー関連の権限を付与したIAMロール (ECSタスクロール) を用意する
以下の定義でIAMポリシーを作成します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel", "ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel" ], "Resource": "*" } ] }
ECSタスクロールを新規作成して、上記で作成したIAMポリシーをアタッチします。
または、既存のECSタスクロールがある場合は、そちらのECSタスクロールにIAMポリシーをアタッチします。
ECSタスクロールの作成手順は下記を参照してください。
タスク用の IAM ロール - Amazon Elastic Container Service
2. 1で用意したECSタスクロールを使って、ECSタスク定義を新規作成または更新する
細かな手順は割愛しますが、一般的な手順 (マネジメントコンソール、AWS CLI、CloudFormation、etc.) でECSタスク定義を新規作成または更新する際に、ステップ1で作成したIAMロールを「タスクロール」に指定してください。
※ 「タスクロール」と「タスク実行ロール」を間違えないように気を付けてください。 アタッチするのは「タスクロール」の方です。
「タスクロール」と「タスク実行ロール」の違いは、こちらのブログ記事が参考になると思います。
3. ECSサービスで「enableExecuteCommand」の設定を有効にする
ECS Exec機能の利用可否は、ECSサービス単位で設定します。
現時点で、AWSマネジメントコンソールの画面からECS Exec機能の利用可否の設定を行ったり、現在の設定状態を確認することはできないようです。
そこで、AWS CLIを使って設定を行うことにします。
ECSサービスを新規作成する場合
ECS Exec機能を有効にするためには、aws ecs create-service
コマンドを実行する際に--enable-execute-command
オプションを付与します。
また、明示的にECS Exec機能を無効にしたい場合は--disable-execute-command
オプションを付与します。
※ 「前提条件」で説明したEC2インスタンスまたはFargateの条件が整っていない場合に--enable-execute-command
オプションを指定すると、エラーが発生します。
作成または更新したECSサービスの設定を確認するには、aws ecs describe-services
コマンドを実行します。
$ aws ecs describe-services \ --cluster example-cluster \ --services example-service { "services": [ { "serviceArn": "arn:aws:ecs:ap-northeast-1:123456789012:service/example-cluster/example-service", "serviceName": "example-service", ・・・(中略)・・・ "enableExecuteCommand": true } ] }
既存のECSサービスの設定を変更する場合
ECS Exec機能を有効にしたい場合は、aws ecs update-service
コマンドに--enable-execute-command
オプションを付けて実行します。
$ aws ecs update-service \ --cluster example-cluster \ --service example-service \ --enable-execute-command
ECS Exec機能を無効にしたい場合は、aws ecs update-service
コマンドに--disable-execute-command
オプションを付けて実行します。
$ aws ecs update-service \ --cluster example-cluster \ --service example-service \ --disable-execute-command
4. 2で作成/更新したECSタスク定義を使って、ECSサービスを新規作成または更新する
こちらも細かな手順は割愛しますが、一般的な手順 (マネジメントコンソール、AWS CLI、CloudFormation、etc.) でECSサービスを新規作成する際にステップ2で作成したECSタスク定義を指定するか、ECSサービスを更新する際にステップ2で更新したECSタスクのリビジョンを指定してください。
なお、ECS Exec機能は「enableExecuteCommand」を有効にした後に起動したタスクでのみ利用可能です。
タスク定義のリビジョンに変更が生じない場合は、サービスの更新の際に「新しいデプロイの強制」にチェックを入れることで、強制的にタスクの起動を行わせるとよいでしょう。
起動したタスクで「enableExecuteCommand」が有効になっているかどうかを確認するには、aws ecs describe-tasks
コマンドを実行します。
$ aws ecs describe-tasks \ --cluster example-cluster \ --tasks XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX { "tasks": [ { "attachments": [ ... ], "availabilityZone": "ap-northeast-1a", ・・・(中略)・・・ "enableExecuteCommand": true, ・・・(中略)・・・ } ] }
ECS Execを使って、コンテナ上でコマンドを実行してみる
さて、準備ができましたので、実際にECS Execを使ってコンテナ上でコマンドを実行してみましょう。
AWS CLIに新たに追加されたコマンドaws ecs execute-command
を使います。
オプションには「ECSクラスター名」「タスクID」「コンテナ名」そして「実行するコマンド」を指定します。
対話形式のコマンド実行を意味する--interactive
オプションは必須ですので注意してください。
なお、--non-interactive
オプションも用意されていますが、現時点では対応していないようです。(指定するとエラーになる)
$ aws ecs execute-command \ --cluster example-clustr \ --task XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \ --container nginx \ --interactive \ --command "ps aux" The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. Starting session with SessionId: ecs-execute-command-XXXXXXXXXXXXXXXXX PID USER TIME COMMAND 1 root 0:00 nginx: master process nginx -g daemon off; 9 nginx 0:00 nginx: worker process 10 root 0:00 /managed-agents/execute-command/amazon-ssm-agent 23 root 0:00 /managed-agents/execute-command/ssm-agent-worker 304 root 0:00 /managed-agents/execute-command/ssm-session-worker ecs-ex 312 root 0:00 ps aux Exiting session with sessionId: ecs-execute-command-XXXXXXXXXXXXXXXXX.
SSMセッションマネージャーのセッションが開始され、コマンドps aux
が実行され、セッションを終了したことが確認できます。
コンテナに対してシェルログインを行いたい場合は、コマンドに/bin/sh
や/bin/bash
を指定します。(当然ながらコンテナにインストールされているシェルしか使えません)
$ aws ecs execute-command \ --cluster example-clustr \ --task XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \ --container nginx \ --interactive \ --command "/bin/sh" The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. Starting session with SessionId: ecs-execute-command-XXXXXXXXXXXXXXXXX / #
これで、コンテナ上で自由にコマンドを実行することができます。
シェルを終了するにはexit
コマンドを実行します。
/ # exit Exiting session with sessionId: ecs-execute-command-XXXXXXXXXXXXXXXXX.
シェルの終了後、SSMセッションマネージャーのセッションも終了します。
おわりに
これで、ECS環境においてコンテナ上のアプリのデバッグやトラブルシューティングが捗るのではないでしょうか。
ECS Execでは他にも「実行したコマンドのロギングと監査」「IAMポリシーによる細かなアクセス制御」などを行うことができます。
これらについては、また調べて試してみたいと思います。